// ==========================================================================
// gin-sns 自动生成model扩展代码列表、增、删，改、查、导出，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/model/module/topic/topic.go
// author：jon
// ==========================================================================
package topic

import (
	"errors"

	"xorm.io/builder"

	"gin-sns/app/ginframe/db"
	"gin-sns/app/ginframe/utils/convert"
	"gin-sns/app/ginframe/utils/excel"
	"gin-sns/app/ginframe/utils/page"

	topicModel "gin-sns/app/model/module/topic"
)

var TopicDao = newTopicDao()

func newTopicDao() *topicDao {
	return &topicDao{}
}

type topicDao struct {
}

//映射数据表
func (d *topicDao) TableName() string {
	return "t_topic"
}

// 插入数据
func (d *topicDao) Insert(e *topicModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).Insert(e)
}

// 更新数据
func (d *topicDao) Update(e *topicModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).ID(e.Id).Update(e)
}

// 删除
func (d *topicDao) Delete(e *topicModel.Entity) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).ID(e.Id).Delete(e)
}

//批量删除
func (d *topicDao) DeleteBatch(ids ...int64) (int64, error) {
	return db.Instance().Engine().Table(d.TableName()).In("id", ids).Delete(new(topicModel.Entity))
}

// 根据结构体中已有的非空数据来获得单条数据
func (d *topicDao) FindOne(e *topicModel.Entity) (bool, error) {
	return db.Instance().Engine().Table(d.TableName()).Get(e)
}

// 根据条件查询
func (d *topicDao) Find(where, order string) ([]topicModel.Entity, error) {
	var list []topicModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).Where(where).OrderBy(order).Find(&list)
	return list, err
}

//指定字段集合查询
func (d *topicDao) FindIn(column string, args ...interface{}) ([]topicModel.Entity, error) {
	var list []topicModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).In(column, args).Find(&list)
	return list, err
}

//排除指定字段集合查询
func (d *topicDao) FindNotIn(column string, args ...interface{}) ([]topicModel.Entity, error) {
	var list []topicModel.Entity
	err := db.Instance().Engine().Table(d.TableName()).NotIn(column, args).Find(&list)
	return list, err
}

//根据主键查询数据
func (d *topicDao) SelectById(id int64) (*topicModel.Entity, error) {
	entity := &topicModel.Entity{Id: id}
	have, err := d.FindOne(entity)
	if !have {
		err = errors.New("not found")
		entity = nil
	}
	return entity, err
}

//根据主键删除数据
func (d *topicDao) DeleteById(id int64) bool {
	entity := &topicModel.Entity{Id: id}
	rs, _ := d.Delete(entity)
	if rs > 0 {
		return true
	}
	return false
}

//批量删除数据记录
func (d *topicDao) DeleteByIds(ids string) int64 {
	ida := convert.ToInt64Array(ids, ",")
	result, err := d.DeleteBatch(ida...)
	if err != nil {
		return 0
	}
	return result
}

//根据条件分页查询数据
func (d *topicDao) SelectListByPage(param *topicModel.SelectPageReq) ([]topicModel.Entity, *page.Paging, error) {
	db := db.Instance().Engine()
	p := new(page.Paging)

	if db == nil {
		return nil, p, errors.New("获取数据库连接失败")
	}

	model := db.Table("t_topic").Alias("t")

	if param != nil {

		if param.ParentId != 0 {
			model.Where("t.parent_id = ?", param.ParentId)
		}

		if param.Title != "" {
			model.Where("t.title = ?", param.Title)
		}

		if param.Description != "" {
			model.Where("t.description = ?", param.Description)
		}

		if param.Logo != "" {
			model.Where("t.logo = ?", param.Logo)
		}

		if param.CountPost != 0 {
			model.Where("t.count_post = ?", param.CountPost)
		}

		if param.CountView != 0 {
			model.Where("t.count_view = ?", param.CountView)
		}

		if param.CountFollow != 0 {
			model.Where("t.count_follow = ?", param.CountFollow)
		}

		if param.Status != 0 {
			model.Where("t.status = ?", param.Status)
		}

		if param.BeginTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') >= date_format(?,'%y%m%d') ", param.BeginTime)
		}

		if param.EndTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') <= date_format(?,'%y%m%d') ", param.EndTime)
		}
	}

	totalModel := model.Clone()
	total, err := totalModel.Count()

	if err != nil {
		return nil, p, errors.New("读取行数失败")
	}

	p = page.CreatePaging(param.PageNum, param.PageSize, int(total))

	model.Limit(p.Pagesize, p.StartNum)

	var result []topicModel.Entity
	err = model.Find(&result)
	return result, p, err
}

// 导出excel
func (d *topicDao) SelectListExport(param *topicModel.SelectPageReq, head, col []string) (string, error) {
	db := db.Instance().Engine()

	if db == nil {
		return "", errors.New("获取数据库连接失败")
	}

	build := builder.Select(col...).From(d.TableName(), "t")

	if param != nil {

		if param.ParentId != 0 {
			build.Where(builder.Eq{"t.parent_id": param.ParentId})
		}

		if param.Title != "" {
			build.Where(builder.Eq{"t.title": param.Title})
		}

		if param.Description != "" {
			build.Where(builder.Eq{"t.description": param.Description})
		}

		if param.Logo != "" {
			build.Where(builder.Eq{"t.logo": param.Logo})
		}

		if param.CountPost != 0 {
			build.Where(builder.Eq{"t.count_post": param.CountPost})
		}

		if param.CountView != 0 {
			build.Where(builder.Eq{"t.count_view": param.CountView})
		}

		if param.CountFollow != 0 {
			build.Where(builder.Eq{"t.count_follow": param.CountFollow})
		}

		if param.Status != 0 {
			build.Where(builder.Eq{"t.status": param.Status})
		}

		if param.BeginTime != "" {
			build.Where(builder.Gte{"date_format(t.create_time,'%y%m%d')": "date_format('" + param.BeginTime + "','%y%m%d')"})
		}

		if param.EndTime != "" {
			build.Where(builder.Lte{"date_format(t.create_time,'%y%m%d')": "date_format('" + param.EndTime + "','%y%m%d')"})
		}
	}

	sqlStr, _, _ := build.ToSQL()
	arr, err := db.SQL(sqlStr).QuerySliceString()

	path, err := excel.DownlaodExcel(head, arr)

	return path, err
}

//获取所有数据
func (d *topicDao) SelectListAll(param *topicModel.SelectPageReq) ([]topicModel.Entity, error) {
	db := db.Instance().Engine()

	if db == nil {
		return nil, errors.New("获取数据库连接失败")
	}

	model := db.Table(d.TableName()).Alias("t")

	if param != nil {

		if param.ParentId != 0 {
			model.Where("t.parent_id = ?", param.ParentId)
		}

		if param.Title != "" {
			model.Where("t.title = ?", param.Title)
		}

		if param.Description != "" {
			model.Where("t.description = ?", param.Description)
		}

		if param.Logo != "" {
			model.Where("t.logo = ?", param.Logo)
		}

		if param.CountPost != 0 {
			model.Where("t.count_post = ?", param.CountPost)
		}

		if param.CountView != 0 {
			model.Where("t.count_view = ?", param.CountView)
		}

		if param.CountFollow != 0 {
			model.Where("t.count_follow = ?", param.CountFollow)
		}

		if param.Status != 0 {
			model.Where("t.status = ?", param.Status)
		}

		if param.BeginTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') >= date_format(?,'%y%m%d') ", param.BeginTime)
		}

		if param.EndTime != "" {
			model.Where("date_format(t.create_time,'%y%m%d') <= date_format(?,'%y%m%d') ", param.EndTime)
		}
	}

	var result []topicModel.Entity
	err := model.Find(&result)
	return result, err
}

// 浏览数+1
func (d *topicDao) IncrFollowCount(followId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_follow = count_follow + 1 where id = ?", followId)
}

func (d *topicDao) DecrFollowCount(followId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_follow = count_follow - 1 where id = ?", followId)
}

// 浏览数+1
func (d *topicDao) IncrViewCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_view = count_view + 1 where id = ?", followedId)
}

func (d *topicDao) DecrViewCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_view = count_view - 1 where id = ?", followedId)
}

func (d *topicDao) IncrPostCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_post= count_post + 1 where id = ?", followedId)
}

func (d *topicDao) DecrPostCount(followedId int64) {
	db := db.Instance().Engine()

	db.Exec("update t_topic set count_post = count_post - 1 where id = ?", followedId)
}
